package com.zlll.winner.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zlll.winner.enums.CommonEnum;
import com.zlll.winner.enums.biz.Constant;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 枚举值操作工具类
 */
public class ConstantUtils {

    /**
     * 返回枚举
     *
     * @param clz
     * @param val
     * @return
     */
    public static Constant getEnumByVal(Class<? extends Constant> clz, String val) {
        try {
            if (!clz.isEnum()) return null;
            Constant[] enums = clz.getEnumConstants();
            for (Constant enumTemp : enums) {
                if (val.equals(String.valueOf(enumTemp.val()))) {
                    return enumTemp;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 根据枚举值class,常量枚举转json数组
     *
     * @param str
     * @return
     */
    public static JSONArray toJSON(String str) {
        return ConstantUtils.toJSON(ConstantUtils.toConstant(str));
    }

    /**
     * 根据枚举值class,常量枚举转list
     *
     * @param str
     * @return
     */
    public static List<Map<String, Object>> toList(String str) {
        return ConstantUtils.toList(ConstantUtils.toConstant(str));
    }

    /**
     * 根据枚举值class,常量枚举转map
     *
     * @param str
     * @return
     */
    public static Map<Integer, String> toMap(String str) {
        return ConstantUtils.toMap(ConstantUtils.toConstant(str));
    }

    private static Constant[] toConstant(String str){
        switch (str){
            case "CommonEnum.YesOrNo" : return CommonEnum.YesOrNo.values();
            default:return new Constant[0];
        }
    }

    /**
     * 常量枚举转json数组
     *
     * @param c
     * @return
     */
    public static JSONArray toJSON(Constant[] c) {
        JSONArray array = new JSONArray();
        for (Constant cc : c) {
            JSONObject obj = new JSONObject();
            obj.put("val", cc.val());
            obj.put("desc", cc.desc());
            array.add(obj);
        }
        return array;
    }

    /**
     * 常量枚举转list
     *
     * @param c
     * @return
     */
    public static List<Map<String, Object>> toList(Constant[] c) {
        List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
        for (Constant cc : c) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("val", cc.val());
            map.put("desc", cc.desc());
            list.add(map);
        }
        return list;
    }

    /**
     * 常量枚举转map
     *
     * @param c
     * @return
     */
    public static Map<Integer, String> toMap(Constant[] c) {
        Map<Integer, String> map = new HashMap<>();
        for (Constant cc : c) {
            map.put(cc.val(), cc.desc());
        }
        return map;
    }

    /**
     * 根据值获取中文
     *
     * @param arr
     * @param val
     * @return
     */
    public static String toDesc(Constant[] arr, int val) {
        for (Constant constant : arr) {
            if (val == constant.val()) return constant.desc();
        }
        return "--";
    }

    /**
     * 判断值是否在枚举中存在  false 存在，true 不存在
     *
     * @param arr
     * @param val
     * @return
     */
    public static boolean toExists(Constant[] arr, int val) {
        boolean flag = true;

        for (Constant constant : arr) {
            if (val == constant.val()) {
                flag = false;
                break;
            }
        }

        return flag;
    }

//    /**
//     * 判断中文是否在枚举中存在  false 存在，true 不存在
//     * @param arr
//     * @param desc
//     * @return
//     */
//    public static boolean toDescExists( Constant[] arr , String desc ){
//        boolean flag = true;
//        if(!StringUtils.isBlank(desc)){
//            for( Constant constant : arr ){
//                if(desc.equals(constant.desc())){
//                    flag = false;
//                    break;
//                }
//            }
//        }
//        return flag;
//    }

    /**
     * 根据中文获取值
     *
     * @param arr
     * @param val
     * @return
     */
    public static int toVal(Constant[] arr, String val) {
        for (Constant constant : arr) {
            if (val.equals(constant.desc())) return constant.val();
        }
        return -1;
    }


    /**
     * @param packageName 包名 com.xw.bear.enums.base
     * @param enumType    枚举名 StoreEnum.AlarmFrequencyEnum
     * @return
     */
    public static Map<String, String> getEnumList(String packageName, String enumType) {
        Map<String, String> map = new HashMap<>();
        String[] enumArray = enumType.split("\\.");
        String subEnum = enumArray[1];
        Class<?> enumClass = null;
        try {
            enumClass = Class.forName(packageName + "." + enumArray[0]);
        } catch (ClassNotFoundException e) {
            return map;
        }
        Class innerClazz[] = enumClass.getDeclaredClasses();
        //遍历内部类
        for (Class innerClass : innerClazz) {
            //获取内部内的类名，在这里其实就是获取枚举类
            String simpleName = innerClass.getSimpleName();
            if (simpleName.equals(subEnum)) {
                //判断类是不是枚举类
                if (innerClass.isEnum()) {
                    //反射获取枚举类
                    Class<Enum> clazz = null;
                    try {
                        clazz = (Class<Enum>) Class.forName(innerClass.getName());
                    } catch (ClassNotFoundException e) {
                        return map;
                    }
                    //获取所有枚举实例
                    Enum[] enumConstants = clazz.getEnumConstants();
                    //根据方法名获取方法
                    try {
                        Method val = clazz.getMethod("val");
                        Method desc = clazz.getMethod("desc");
                        for (Enum enum1 : enumConstants) {
                            //执行枚举方法获得枚举实例对应的值
                            try {
                                Object invoke1 = val.invoke(enum1);
                                Object invoke2 = desc.invoke(enum1);
                                map.put(invoke1.toString(), invoke2.toString());
                            } catch (IllegalAccessException e) {
                                e.printStackTrace();
                            } catch (InvocationTargetException e) {
                                e.printStackTrace();
                            }
                        }
                    } catch (NoSuchMethodException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
        return map;
    }

}
